# -*- coding: utf-8 -*-
import cv2
import threading
import time
class ClsFeeder(object):
    def __init__(self,name,feeder,read_data_function):
        super().__init__()
        self.name=name
        self.read_data=read_data_function
class ClsProcessor(object):
    def __init__(self,name,processor,put_data_function,data_source_name,process_function,get_result_function):
        super().__init__()
        self.name=name
        self.put_data=put_data_function #统一存储数据的function名称
        self.data_source_name=data_source_name
        self.process=process_function #统一存储数据的function名称
        self.get_result=get_result_function #统一存储数据的function名称，供外部调用

class DataFeeder(threading.Thread):
    def __init__(self, thread_delay):
        super().__init__()
        self.exitFlag=False
        self.threadLocker=threading.Lock()
        self.delay=thread_delay
        #------------数据获取器-------------
        self.feeders={} #可以是多个输入来源
        self.data={} #存储多个输入来源的数据
        #------------数据处理器-------------
        self.processors={} #可以是多个处理器
        self.result={}


    def regist_feeder(self,name,feeder,read_data_function):
        #新建一个data feeder
        self.feeders[name]=ClsFeeder(name,feeder,read_data_function)
        #self.feeders[name].read_data=read_data_function #统一读取数据的function名称
        self.data[name]=''
    
    def regist_processor(self,name,processor,put_data_function,data_source_name,process_function,get_result_function):
        '''
        新建一个data processor
        重命名每个processor的数据获取功能、处理功能、结果获取功能
        put_data_function: 计算单元填喂数据的function名
        data_source_name: 计算单元需要填喂的数据名称，应该是feeders中的一个
        process_function: 计算单元处理数据的function名
        '''
        self.processors[name]=ClsProcessor(name,processor,put_data_function,data_source_name,process_function,get_result_function)
        self.result[name]=''
    def get_result(self,processor_name):
        return self.processors[processor_name].get_result()

    def run(self):
        """
        目标检测线程启动
        """
        print ("开始目标检测子线程：" + self.name)
        self.__thread_calculate__(self.name, self.delay)
        print ("退出目标检测子线程：" + self.name)

    def __thread_calculate__(self,threadName, delay):
        while 1:
            if self.exitFlag:
                print('self.exitFlat = ',self.exitFlag)
                break
            else:
                #-----------------从各个计算单元获取结果---------------------
                # 注释掉的原因是，不再实时获取结果，而是在外部需要结果的时候，通过get_result功能联通与object detector的数据
                #for processor_key in self.processors.keys():
                #    self.result[processor_key]=self.processors[processor_key].get_result()
                datatmp=self.processors['objDetector'].get_result()
                print(datatmp)
                #-----------------从各个数据源获取数据---------------------
                self.threadLocker.acquire()
                for reader_key in self.feeders.keys():
                    self.data[reader_key]=self.feeders[reader_key].read_data()
                self.threadLocker.release() 
                #----------------为每个计算单元填入数据并进行处理-----------
                for processor_key in self.processors.keys():
                    data_to_put=self.data[self.processors[processor_key].data_source_name]
                    if(len(data_to_put)>0):
                        self.processors[processor_key].put_data(data_to_put) ##需要完善
                        self.processors[processor_key].process()
            time.sleep(delay)
    def exit(self):
        self.exitFlag=True

if __name__=='__main__':
    import os
    PBTXT_PATH=r'../model/saved_model.pbtxt'
    SAVED_MODEL_DIR =os.path.abspath( r'../model/ecu_damper_789/saved_model')
    TEST_IMG_DIR=r'D:\OneDrive - Continental AG\Dataset\ecu_damper\color\20200722-f05'

    from general_utils import clsCamera
    from cores import object_detect

    cam=clsCamera.clsGeneralCamera(clsCamera.CAMERA.GENERAL_USB)
    camThread=clsCamera.clsCameraThread('camThread',cam)

    obj_detector=object_detect.ObjectDetectionExt(pbtxt_path=PBTXT_PATH,saved_model_dir=SAVED_MODEL_DIR)
    #objThread=object_detect.clsObjectDetectorThread('objDetectThread',obj_detector)

    myFeeder=DataFeeder(0.1) # 0.1秒执行一次
    myFeeder.regist_feeder(
        'cameraThread',
        camThread,
        camThread.getNumpyImage
    )

    myFeeder.regist_processor(
        'objDetector',
        obj_detector,
        obj_detector.putImage_RGB_np,
        'cameraThread',
        obj_detector.startInfer,
        obj_detector.getResultImgAndDicts
    )

    camThread.start()
    myFeeder.start()

    while(1):
        keyin=input('input command')
        if(keyin.strip()=='q'.strip()):
            break
    myFeeder.exit()
    camThread.exit()
    
